<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue';
import dayjs, { type Dayjs } from 'dayjs';
import { useBoolean } from '@sa/hooks';
import { deleteHoliday, fetchHolidaysByCurrency, insertHoliday } from '@/service/api/holiday';

// 假日数据接口
interface HolidayData {
  id?: number;
  currencyCode: string;
  holidayDate: string;
  dayType: number; // 0-假日，1-调休工作日
  holidayNameEn?: string;
  createTime?: string;
  updateTime?: string;
}

interface Emits {
  (e: 'close'): void;
}

interface Props {
  open: boolean;
  currencyCode: string;
}

defineOptions({
  name: 'CurrencyHolidayModal'
});

const props = defineProps<Props>();
const emit = defineEmits<Emits>();

const loading = ref(false);
const { setFalse: hideAddForm } = useBoolean();
const batchMode = ref(false);

const holidayData = ref<HolidayData[]>([]);
const selectedDate = ref<Dayjs>(dayjs());
const selectedDates = ref<Set<string>>(new Set());

const addForm = reactive({
  holidayDate: '',
  dayType: 0, // 默认为假日
  holidayNameEn: ''
});

const visible = computed({
  get() {
    return props.open;
  },
  set(value) {
    if (!value) {
      emit('close');
    }
  }
});

// 假日日期集合（只包含假日，不包含调休工作日）
const holidayDates = computed(() => {
  return new Set(
    holidayData.value
      .filter(holiday => holiday.dayType === 0) // 只包含假日
      .map(holiday => {
        // 处理后端返回的ISO日期格式，转换为YYYY-MM-DD格式
        const date = new Date(holiday.holidayDate);
        return dayjs(date).format('YYYY-MM-DD');
      })
  );
});

// 调休工作日日期集合
const workdayDates = computed(() => {
  return new Set(
    holidayData.value
      .filter(holiday => holiday.dayType === 1) // 只包含调休工作日
      .map(holiday => {
        // 处理后端返回的ISO日期格式，转换为YYYY-MM-DD格式
        const date = new Date(holiday.holidayDate);
        return dayjs(date).format('YYYY-MM-DD');
      })
  );
});

// 判断是否为手动设置的假日
function isManualHoliday(date: Dayjs): boolean {
  const dateStr = date.format('YYYY-MM-DD');
  return holidayDates.value.has(dateStr);
}

// 判断是否为调休工作日
function isWorkday(date: Dayjs): boolean {
  const dateStr = date.format('YYYY-MM-DD');
  return workdayDates.value.has(dateStr);
}

// 日期选择处理
function onDateSelect(date: Dayjs) {
  if (batchMode.value) {
    const dateStr = date.format('YYYY-MM-DD');
    const newSelectedDates = new Set(selectedDates.value);

    if (newSelectedDates.has(dateStr)) {
      newSelectedDates.delete(dateStr);
    } else {
      newSelectedDates.add(dateStr);
    }

    selectedDates.value = newSelectedDates;
  }
}

async function getHolidayData() {
  if (!props.currencyCode) return;

  loading.value = true;
  try {
    const { data: resData, error } = await fetchHolidaysByCurrency(props.currencyCode);
    if (resData) {
      holidayData.value = resData;
    } else {
      console.error('获取假日数据失败:', error);
      holidayData.value = [];
    }
  } catch (error) {
    console.error('获取数据失败:', error);
  } finally {
    loading.value = false;
  }
}

// 判断日期是否被选中
function isDateSelected(date: Dayjs): boolean {
  const dateStr = date.format('YYYY-MM-DD');
  return selectedDates.value.has(dateStr);
}

// 处理右键菜单点击
async function handleContextMenuClick(info: any, date: Dayjs) {
  const dateStr = date.format('YYYY-MM-DD');
  const key = String(info.key);

  try {
    if (key === 'holiday') {
      // 添加假日
      const { error } = await insertHoliday({
        currencyCode: props.currencyCode,
        holidayDate: dateStr,
        dayType: 0,
        holidayNameEn: ''
      });

      if (!error) {
        window.$message?.success('设置假日成功');
        getHolidayData();
      } else {
        console.error('设置假日失败:', error);
      }
    } else if (key === 'workday') {
      // 添加调休工作日
      const { error } = await insertHoliday({
        currencyCode: props.currencyCode,
        holidayDate: dateStr,
        dayType: 1,
        holidayNameEn: ''
      });
      if (!error) {
        window.$message?.success('设置为调休工作日成功');
        getHolidayData();
      } else {
        console.error('设置调休工作日失败:', error);
      }
    } else if (key === 'remove') {
      // 删除记录
      const { error } = await deleteHoliday(props.currencyCode, dateStr);
      if (!error) {
        window.$message?.success('删除成功');
        getHolidayData();
      } else {
        console.error('删除失败:', error);
      }
    }
  } catch (error) {
    console.error('操作失败:', error);
  }
}

function handleClose() {
  visible.value = false;
  hideAddForm();
  addForm.holidayDate = '';
  addForm.dayType = 0;
  addForm.holidayNameEn = '';
  selectedDate.value = dayjs();
}

watch(
  () => props.open,
  newVal => {
    if (newVal && props.currencyCode) {
      getHolidayData();
    }
  }
);

watch(
  () => props.currencyCode,
  newVal => {
    if (newVal && props.open) {
      getHolidayData();
    }
  }
);
</script>

<template>
  <AModal v-model:open="visible" :title="`${currencyCode} 假日管理`" width="800px" @cancel="handleClose">
    <template #footer>
      <AButton @click="handleClose">关闭</AButton>
    </template>

    <div class="space-y-4">
      <!-- 日历管理 -->
      <ACard size="small" title="日历管理">
        <ASpin :spinning="loading">
          <div class="calendar-wrapper">
            <ACalendar v-model:value="selectedDate" :fullscreen="false">
              <template #dateFullCellRender="{ current }">
                <ADropdown :trigger="['contextmenu']" @contextmenu.prevent>
                  <div
                    class="date-cell"
                    :class="{
                      'holiday-cell': isManualHoliday(current),
                      'workday-cell': isWorkday(current),
                      'normal-cell': !isManualHoliday(current) && !isWorkday(current),
                      'selected-cell': batchMode && isDateSelected(current)
                    }"
                    @click="onDateSelect(current)"
                  >
                    <div class="date-number">{{ current.date() }}</div>
                    <div v-if="isWorkday(current)" class="workday-mark">班</div>
                    <div v-if="isManualHoliday(current)" class="holiday-mark">休</div>
                  </div>
                  <template #overlay>
                    <AMenu @click="info => handleContextMenuClick(info, current)">
                      <template v-if="!isManualHoliday(current) && !isWorkday(current)">
                        <AMenuItem key="holiday">
                          <span>设为假日</span>
                        </AMenuItem>
                        <AMenuItem key="workday">
                          <span>设为调休工作日</span>
                        </AMenuItem>
                      </template>
                      <template v-else-if="isManualHoliday(current) || isWorkday(current)">
                        <AMenuItem key="remove">
                          <span>设置为工作日</span>
                        </AMenuItem>
                      </template>
                    </AMenu>
                  </template>
                </ADropdown>
              </template>
            </ACalendar>
          </div>

          <!-- 操作说明 -->
          <div class="operation-tips">
            <AAlert
              message="操作说明"
              description="右键点击日期可以设置为假日或调休工作日。灰色背景表示普通工作日，绿色背景表示假日，红色背景表示调休工作日。"
              type="info"
              show-icon
            />
          </div>
        </ASpin>
      </ACard>
    </div>
  </AModal>
</template>

<style scoped>
.add-form {
  padding: 16px;
  background-color: #fafafa;
  border-radius: 6px;
}

.space-y-4 > * + * {
  margin-top: 16px;
}

.calendar-wrapper {
  margin-bottom: 16px;
}

.date-cell {
  position: relative;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color 0.2s ease;
  border-radius: 4px;
  margin: 0 auto;
}

.date-cell:hover {
  opacity: 0.8;
}

.holiday-cell {
  background-color: #f2ffea;
  color: #52c41a;
  border: 1px solid #b7eb8f;
}

.workday-cell {
  background-color: #ffedf1;
  color: #c41a1a;
  border: 1px solid #eb8f9d;
}

.normal-cell {
  background-color: #eaeaea5b;
  color: #000000;
}

.selected-cell {
  background-color: #1890ff !important;
  color: white !important;
  border: 2px solid #0050b3;
}

.mb-4 {
  margin-bottom: 16px;
}

.date-number {
  font-size: 14px;
  font-weight: 500;
}

.workday-mark {
  position: absolute;
  top: 1px;
  right: 0px;
  font-size: 10px;
  color: #c41a36;
  font-weight: bold;
  background-color: #ffffff00;
  border-radius: 2px;
  padding: 0 2px;
  line-height: 1;
}
.holiday-mark {
  position: absolute;
  top: 1px;
  right: 0px;
  font-size: 10px;
  color: #52c41a;
  font-weight: bold;
  background-color: #ffffff00;
  border-radius: 2px;
  padding: 0 2px;
  line-height: 1;
}
.operation-tips {
  margin-top: 16px;
}

:deep(.ant-picker-calendar-date-content) {
  height: 60px;
}

:deep(.ant-picker-cell-in-view.ant-picker-cell-selected .ant-picker-calendar-date) {
  background-color: #e6f7ff;
  border-color: #1890ff;
}

:deep(.ant-picker-cell:hover .ant-picker-calendar-date) {
  background-color: #f5f5f5;
  cursor: pointer;
}
</style>
